import * as THREE from 'three';
import { OBJExporter } from './OBJExporter';
import { STLExporter } from './STLExporter';
import { GLTFExporter } from './GLTFExporter';

// 将模型数据转换为Three.js对象
function createThreeObject(modelData) {
    const scene = new THREE.Scene();

    // 处理主几何体
    if (modelData.geometry) {
        const geometry = modelData.geometry;
        let mesh;

        if (geometry.type === 'cube') {
            const boxGeometry = new THREE.BoxGeometry(
                geometry.dimensions?.width || 1,
                geometry.dimensions?.height || 1,
                geometry.dimensions?.depth || 1
            );
            const material = new THREE.MeshStandardMaterial({ color: geometry.color || '#3366FF' });
            mesh = new THREE.Mesh(boxGeometry, material);
        } else if (geometry.type === 'sphere') {
            const sphereGeometry = new THREE.SphereGeometry(
                geometry.dimensions?.radius || 1,
                geometry.dimensions?.segments || 32,
                geometry.dimensions?.segments || 32
            );
            const material = new THREE.MeshStandardMaterial({ color: geometry.color || '#3366FF' });
            mesh = new THREE.Mesh(sphereGeometry, material);
        } else if (geometry.type === 'cylinder') {
            const cylinderGeometry = new THREE.CylinderGeometry(
                geometry.dimensions?.radius || 1,
                geometry.dimensions?.radius || 1,
                geometry.dimensions?.height || 2,
                geometry.dimensions?.segments || 32
            );
            const material = new THREE.MeshStandardMaterial({ color: geometry.color || '#3366FF' });
            mesh = new THREE.Mesh(cylinderGeometry, material);
        } else if (geometry.type === 'cone') {
            const coneGeometry = new THREE.ConeGeometry(
                geometry.dimensions?.radius || 1,
                geometry.dimensions?.height || 2,
                geometry.dimensions?.segments || 32
            );
            const material = new THREE.MeshStandardMaterial({ color: geometry.color || '#3366FF' });
            mesh = new THREE.Mesh(coneGeometry, material);
        } else if (geometry.type === 'torus') {
            const torusGeometry = new THREE.TorusGeometry(
                geometry.dimensions?.radius || 1,
                geometry.dimensions?.tube || 0.4,
                geometry.dimensions?.radialSegments || 16,
                geometry.dimensions?.tubularSegments || 100
            );
            const material = new THREE.MeshStandardMaterial({ color: geometry.color || '#3366FF' });
            mesh = new THREE.Mesh(torusGeometry, material);
        } else if (geometry.type === 'pyramid') {
            // 使用自定义几何体创建金字塔
            const width = geometry.dimensions?.width || 1;
            const height = geometry.dimensions?.height || 1.5;
            const depth = geometry.dimensions?.depth || 1;

            const pyramidGeometry = new THREE.BufferGeometry();
            const vertices = new Float32Array([
                // 底部矩形
                -width / 2, 0, -depth / 2,
                width / 2, 0, -depth / 2,
                width / 2, 0, depth / 2,
                -width / 2, 0, depth / 2,
                // 顶点
                0, height, 0
            ]);

            const indices = new Uint16Array([
                // 底部矩形
                0, 1, 2,
                0, 2, 3,
                // 侧面
                0, 4, 1,
                1, 4, 2,
                2, 4, 3,
                3, 4, 0
            ]);

            pyramidGeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
            pyramidGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
            pyramidGeometry.computeVertexNormals();

            const material = new THREE.MeshStandardMaterial({ color: geometry.color || '#3366FF' });
            mesh = new THREE.Mesh(pyramidGeometry, material);
        }

        if (mesh) {
            mesh.position.set(
                geometry.position?.x || 0,
                geometry.position?.y || 0,
                geometry.position?.z || 0
            );
            mesh.rotation.set(
                geometry.rotation?.x || 0,
                geometry.rotation?.y || 0,
                geometry.rotation?.z || 0
            );
            scene.add(mesh);
        }

        // 处理额外几何体
        if (Array.isArray(modelData.additionalObjects)) {
            modelData.additionalObjects.forEach(obj => {
                let additionalMesh;

                if (obj.type === 'cube') {
                    const boxGeometry = new THREE.BoxGeometry(
                        obj.dimensions?.width || 1,
                        obj.dimensions?.height || 1,
                        obj.dimensions?.depth || 1
                    );
                    const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                    additionalMesh = new THREE.Mesh(boxGeometry, material);
                } else if (obj.type === 'sphere') {
                    const sphereGeometry = new THREE.SphereGeometry(
                        obj.dimensions?.radius || 1,
                        obj.dimensions?.segments || 32,
                        obj.dimensions?.segments || 32
                    );
                    const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                    additionalMesh = new THREE.Mesh(sphereGeometry, material);
                } else if (obj.type === 'cylinder') {
                    const cylinderGeometry = new THREE.CylinderGeometry(
                        obj.dimensions?.radius || 1,
                        obj.dimensions?.radius || 1,
                        obj.dimensions?.height || 2,
                        obj.dimensions?.segments || 32
                    );
                    const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                    additionalMesh = new THREE.Mesh(cylinderGeometry, material);
                } else if (obj.type === 'cone') {
                    const coneGeometry = new THREE.ConeGeometry(
                        obj.dimensions?.radius || 1,
                        obj.dimensions?.height || 2,
                        obj.dimensions?.segments || 32
                    );
                    const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                    additionalMesh = new THREE.Mesh(coneGeometry, material);
                } else if (obj.type === 'torus') {
                    const torusGeometry = new THREE.TorusGeometry(
                        obj.dimensions?.radius || 1,
                        obj.dimensions?.tube || 0.4,
                        obj.dimensions?.radialSegments || 16,
                        obj.dimensions?.tubularSegments || 100
                    );
                    const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                    additionalMesh = new THREE.Mesh(torusGeometry, material);
                } else if (obj.type === 'pyramid') {
                    // 使用自定义几何体创建金字塔
                    const width = obj.dimensions?.width || 1;
                    const height = obj.dimensions?.height || 1.5;
                    const depth = obj.dimensions?.depth || 1;

                    const pyramidGeometry = new THREE.BufferGeometry();
                    const vertices = new Float32Array([
                        // 底部矩形
                        -width / 2, 0, -depth / 2,
                        width / 2, 0, -depth / 2,
                        width / 2, 0, depth / 2,
                        -width / 2, 0, depth / 2,
                        // 顶点
                        0, height, 0
                    ]);

                    const indices = new Uint16Array([
                        // 底部矩形
                        0, 1, 2,
                        0, 2, 3,
                        // 侧面
                        0, 4, 1,
                        1, 4, 2,
                        2, 4, 3,
                        3, 4, 0
                    ]);

                    pyramidGeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
                    pyramidGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
                    pyramidGeometry.computeVertexNormals();

                    const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                    additionalMesh = new THREE.Mesh(pyramidGeometry, material);
                }

                if (additionalMesh) {
                    additionalMesh.position.set(
                        obj.position?.x || 0,
                        obj.position?.y || 0,
                        obj.position?.z || 0
                    );
                    additionalMesh.rotation.set(
                        obj.rotation?.x || 0,
                        obj.rotation?.y || 0,
                        obj.rotation?.z || 0
                    );
                    scene.add(additionalMesh);
                }
            });
        }
    } else if (Array.isArray(modelData.objects)) {
        // 处理对象数组（来自ThreeModelEditor的数据）
        modelData.objects.forEach(obj => {
            let meshOrGroup; // 可能是一个Mesh或一个Group (来自外部模型)

            if (obj.type === 'box') {
                const boxGeometry = new THREE.BoxGeometry(
                    obj.size?.width || 1,
                    obj.size?.height || 1,
                    obj.size?.depth || 1
                );
                const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                meshOrGroup = new THREE.Mesh(boxGeometry, material);
            } else if (obj.type === 'sphere') {
                const sphereGeometry = new THREE.SphereGeometry(
                    obj.radius || 1,
                    32,
                    32
                );
                const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                meshOrGroup = new THREE.Mesh(sphereGeometry, material);
            } else if (obj.type === 'cylinder') {
                const cylinderGeometry = new THREE.CylinderGeometry(
                    obj.radius || 1,
                    obj.radius || 1,
                    obj.height || 2,
                    32
                );
                const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                meshOrGroup = new THREE.Mesh(cylinderGeometry, material);
            } else if (obj.type === 'cone') {
                const coneGeometry = new THREE.ConeGeometry(
                    obj.radius || 1,
                    obj.height || 2,
                    32
                );
                const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                meshOrGroup = new THREE.Mesh(coneGeometry, material);
            } else if (obj.type === 'torus') {
                const torusGeometry = new THREE.TorusGeometry(
                    obj.radius || 1,
                    obj.tube || 0.4,
                    16,
                    100
                );
                const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                meshOrGroup = new THREE.Mesh(torusGeometry, material);
            } else if (obj.type === 'pyramid') {
                // 使用自定义几何体创建金字塔
                const width = obj.size?.width || 1;
                const height = obj.size?.height || 1.5;
                const depth = obj.size?.depth || 1;

                const pyramidGeometry = new THREE.BufferGeometry();
                const vertices = new Float32Array([
                    // 底部矩形
                    -width / 2, 0, -depth / 2,
                    width / 2, 0, -depth / 2,
                    width / 2, 0, depth / 2,
                    -width / 2, 0, depth / 2,
                    // 顶点
                    0, height, 0
                ]);

                const indices = new Uint16Array([
                    // 底部矩形
                    0, 1, 2,
                    0, 2, 3,
                    // 侧面
                    0, 4, 1,
                    1, 4, 2,
                    2, 4, 3,
                    3, 4, 0
                ]);

                pyramidGeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
                pyramidGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
                pyramidGeometry.computeVertexNormals();

                const material = new THREE.MeshStandardMaterial({ color: obj.color || '#3366FF' });
                meshOrGroup = new THREE.Mesh(pyramidGeometry, material);
            } else if (obj.type === 'external_model') {
                // *** 新增：处理外部模型 ***
                console.log('处理外部模型导出:', obj.externalId);
                if (modelData.externalModels && obj.externalId) {
                    const loadedExternalModel = modelData.externalModels.find(extModel => extModel.id === obj.externalId);
                    if (loadedExternalModel && loadedExternalModel.originalObject) {
                        console.log('找到已加载的外部模型数据，准备克隆并添加到导出场景');
                        // 克隆模型以避免修改原始对象
                        const clonedObject = loadedExternalModel.originalObject.clone();

                        // 设置变换
                        clonedObject.position.set(
                            obj.position?.x || 0,
                            obj.position?.y || 0,
                            obj.position?.z || 0
                        );
                        clonedObject.rotation.set(
                            obj.rotation?.x || 0,
                            obj.rotation?.y || 0,
                            obj.rotation?.z || 0
                        );
                        clonedObject.scale.set(
                            obj.scale?.x || 1,
                            obj.scale?.y || 1,
                            obj.scale?.z || 1
                        );

                        // 应用颜色 (尝试遍历设置材质颜色)
                        const objectColor = new THREE.Color(obj.color || '#FFFFFF');
                        clonedObject.traverse((child) => {
                            if (child.isMesh && child.material) {
                                // 克隆材质以避免影响原始对象
                                if (Array.isArray(child.material)) {
                                    child.material = child.material.map(mat => {
                                        const clonedMat = mat.clone();
                                        clonedMat.color = objectColor;
                                        return clonedMat;
                                    });
                                } else {
                                    child.material = child.material.clone();
                                    child.material.color = objectColor;
                                }
                            }
                        });

                        meshOrGroup = clonedObject;
                    } else {
                        console.warn(`未能在 externalModels 数组中找到 ID 为 ${obj.externalId} 的已加载模型数据，无法导出该对象。`);
                    }
                } else {
                    console.warn(`externalModels 数组不存在或对象缺少 externalId，无法导出外部模型 ${obj.fileName}`);
                }
            }

            if (meshOrGroup) { // 修改：检查 meshOrGroup
                scene.add(meshOrGroup); // 修改：添加 meshOrGroup
            }
        });
    }

    return scene;
}

// 导出OBJ格式
async function exportToOBJ(modelData) {
    const scene = createThreeObject(modelData);
    const exporter = new OBJExporter();
    const objString = exporter.parse(scene);

    return objString;
}

// 导出STL格式
async function exportToSTL(modelData, binary = false) {
    const scene = createThreeObject(modelData);
    const exporter = new STLExporter();
    const result = exporter.parse(scene, { binary });

    return result;
}

// 导出GLB格式
async function exportToGLB(modelData) {
    const scene = createThreeObject(modelData);
    const exporter = new GLTFExporter();

    try {
        const result = await exporter.parse(scene, { binary: true });
        return result;
    } catch (error) {
        console.error('导出GLB失败:', error);
        throw error;
    }
}

// 下载文件的辅助函数
function downloadFile(data, filename, mimeType) {
    let blob;

    if (data instanceof ArrayBuffer || data instanceof Blob) {
        blob = new Blob([data], { type: mimeType });
    } else {
        // 文本数据
        blob = new Blob([data], { type: mimeType });
    }

    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();

    // 清理
    setTimeout(() => {
        URL.revokeObjectURL(link.href);
    }, 100);
}

// 导出模型（统一接口）
async function exportModel(modelData, format, fileName) {
    try {
        let result;
        let mimeType;
        let fileExtension;

        switch (format) {
            case 'obj':
                result = await exportToOBJ(modelData);
                mimeType = 'application/x-tgif';
                fileExtension = '.obj';
                break;

            case 'stl':
                result = await exportToSTL(modelData, false); // 文本STL
                mimeType = 'application/vnd.ms-pki.stl';
                fileExtension = '.stl';
                break;

            case 'glb':
                result = await exportToGLB(modelData);
                mimeType = 'model/gltf-binary';
                fileExtension = '.glb';
                break;

            default:
                throw new Error(`不支持的格式: ${format}`);
        }

        const modelName = modelData.name || '模型';
        const finalFileName = `${fileName || modelName}${fileExtension}`;

        downloadFile(result, finalFileName, mimeType);

        return true;
    } catch (error) {
        console.error(`导出模型为${format}失败:`, error);
        throw error;
    }
}

export { exportModel }; 